package cn.buk.tms.eotms.entity;

import com.fasterxml.jackson.annotation.JsonFormat;
import jakarta.persistence.Table;
import jakarta.persistence.UniqueConstraint;

import jakarta.persistence.*;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 账单信息
 *
 * @author yfdai
 * @date 2017/7/10
 */
@Entity
@Table(name = "t301", uniqueConstraints = @UniqueConstraint(name = "uk_t301",columnNames = {"enterprise_id", "billNum"}))
public class BillInfo {

    public static final String BILL_TYPE_FLIGHT = "0"; //机票
    public static final String BILL_TYPE_CREDENCE = "1"; //换开凭证
    public static final String BILL_TYPE_HOTEL = "2"; //酒店
    public static final String BILL_TYPE_TRAIN = "3"; //火车票
    public static final String BILL_TYPE_CAR = "4"; //租车
    public static final String BILL_TYPE_FLIGHT_REFUND = "5"; //飞机票退票
    public static final String BILL_TYPE_VAS = "6"; //增值服务
    public static final String BILL_TYPE_FLIGHT_CHANGE = "7"; //飞机票改签

    public static final String PAY_TYPE_CASH = "1"; //现金
    public static final String PAY_TYPE_CREDIT_CARD = "2"; //信用卡
    public static final String PAY_TYPE_CHECK = "4"; //支票
    public static final String PAY_TYPE_BILL = "8"; //记账

    /**
     * 已收款(买家付款已收到）
     */
    public static final String CUSTOMER_PAYMENT_RECEIVED = "1";

    /**
     * 未收款(买家未付款)
     */
    public static final String CUSTOMER_PAYMENT_NOT_RECEIVED = "0";


    /**
     * 已付（支付给供应商）
     */
    public static final int PAYMENT_MADE = 1;

    /**
     * 未付（未支付给供应商）
     */
    public static final int PAYMENT_DUE = 0;

    public static final String BILL_AUDITED = "1"; // 账单已审核
    public static final String BILL_NOT_AUDITED = "0"; // 账单未审核

    public static final String MANUAL_WRITE_OFF_REMARK = "手工单张销账"; //手工销账备注

    @Id
    @GeneratedValue(strategy= GenerationType.IDENTITY)
    private int id;

    @Column(name = "enterprise_id", updatable = false)
    private int enterpriseId;

    /**
     * 账单号
     */
    @Column(length = 32)
    private String billNum;

    /**
     * 账单类型
     */
    @Column(name = "billtype")
    private String billType;


    /**
     * 账单金额
     */
    private double billSum;

    /**
     * 客户类型
     * 0 - 代表散客
     * 1 - 代表企业客户
     */
    @Column(name="customer_type")
    private Integer customerType;

    /**
     * 客户在系统中的id: 在t102中对应的ID，是plutus录入时保存的
     */
    @ManyToOne
    @JoinColumn(name="customer_id", foreignKey = @ForeignKey(name = "fk_t301_customer"))
    private Customer customer;


    @Column(name = "customer_id", insertable = false, updatable = false)
    private Integer customerId;

    /**
     * 客户编号(用于显示）(企业散客：到账单里变为散客，此处则记录它的客户代码）
     */
    @Column(name = "customer_code", length = 30)
    private String customerCode;

    /**
     * 成本中心
     */
    @Column(name = "cost_center", length = 50)
    private String costCenter;

    /**
     * 项目名称
     */
    @Column(name = "project_name", length = 50)
    private String projectName;


    /**
     * 账单日期：该账单录入的日期
     */
    @JsonFormat(pattern = "yyyy-MM-dd",timezone="GMT+8")
    @Temporal(TemporalType.DATE)
    private Date opDate;

    /**
     * 出票日期
     */
    @JsonFormat(pattern = "yyyy-MM-dd",timezone="GMT+8")
    @Temporal(TemporalType.DATE)
    @Column(name = "etdz_date")
    private Date etdzDate;

    /**
     * 创建此账单的用户名
     */
    @Column(length = 32)
    private String operator;


    /**
     * 订票人，对应flightOrder.operator
     */
    @Column(length = 32)
    private String op1;


    /**
     * 该账单客户的付款方式
     * 1-现金；
     * 2-信用卡；
     * 4-支票；
     * 8-记账
     */
    @Column(name = "paytypenote", length = 2)
    private String payTypeNote;

    /**
     * 客户付款备注
     */
    @Column(name = "pay_remark")
    private String payRemark;

    /**
     * 是否已审核
     * 0/null - 未审核
     * 1 - 已审核
     */
    @Column(name = "BeAudited", length = 1)
    private String audited = "0";

    /**
     * 审核日期
     */
    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
    @Temporal(TemporalType.DATE)
    @Column(name = "audit_date")
    private Date auditDate;

    /**
     * 结算日期
     */
    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
    @Temporal(TemporalType.DATE)
    @Column(name = "settle_date")
    private Date settleDate;

    /**
     * 结算单号
     */
    @Column(name = "settlement_no", length = 20)
    private String settlementNo;

    /**
     * 销账日期
     */
    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
    @Temporal(TemporalType.DATE)
    private Date writeOffDate;

    /**
     * 销账备注
     */
    @Column(length = 50)
    private String writeOffMemo;

    /**
     * 是否已收款
     * 0/null: 未收
     * 1: 已收
     */
    @Column(name = "BePayed", length = 1)
    private String bePaid;

    /**
     * 付款状态（付款给供应商）
     * 0/null: 未付
     * 1: 已付
     */
    @Column(name = "payment_status")
    private Integer paymentStatus;

    /**
     * 销账所使用的收款单号
     */
    @Column(name = "receipt_no", length = 32)
    private String receiptNo;

    /**
     * 该账单金额是否记录的ent_balance中
     * 是否已处理
     * 1-是
     * 0、null-没有处理
     */
    @Column(name = "is_processed")
    private Integer beProcessed;

    /**
     * 对应类型的订单号
     * 机票账单：机票订单号
     * 退票账单：退票订单号
     * 改签账单：改签订单号
     * 等
     */
    @Column(name = "order_no", length = 10)
    private String orderNo;

    /**
     * 冗余字段：
     * 退票，改签，服务单对应的机票订单号
     */
    @Column(name = "flight_order_no", length = 10)
    private String flightOrderNo;

    /**
     * 是否国际
     * null/-1 不知道
     * 0 - 否
     * 1 - 是
     */
    @Column(name = "intl_ticket")
    private Integer intlTicket;

    /**
     * 冗余字段，用于记录该账单包括了几张机票；
     * 退票账单： 1；
     * 改签账单： 1；
     * 机票账单： n;
     */
    @Column(name = "ticket_count")
    private Integer ticketCount;

    /**
     * 冗余字段，用于统计
     * 航空公司代码：用于统计报表的冗余字段
     */
    @Column(length = 2)
    private String carrier;

    /**
     * 账单备注
     */
    private String remark;

    /**
     * 订单保存数据库的时间：系统自动生成
     */
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
    @Temporal(TemporalType.TIMESTAMP)
    @Column(name="create_time", insertable = false, updatable = false)
    private Date createTime;

    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
    @Temporal(TemporalType.TIMESTAMP)
    @Column(insertable = false)
    private Date lastUpdate;

    @Transient
    private List<BillFlightTicket> tickets;

    @Transient
    private List<BillFlightRefundTicket> refundTickets;

    @Transient
    private List<BillChangeOrder> changeOrders;

    @Transient
    private List<BillTrainTicket> trainTickets;

    @Transient
    private List<BillHotelBooking> hotelBookings;

    @Transient
    private List<BillVasOrder> vasOrders;

    /**
     * 输出给前端用
     * @return
     */
    public String getPayTypeNoteDesc() {
        return getPayTypeNoteDesc(this.payTypeNote);
    }


    public static String getPayTypeNoteDesc(String val) {
        if ("1".equals(val)) {
            return "现金";
        } else if ("2".equals(val)) {
            return "信用卡";
        }if ("4".equals(val)) {
            return "支票";
        }if ("8".equals(val)) {
            return "记账";
        } else {
            return val;
        }
    }

    public String getAuditedDesc() {
        if ("0".equalsIgnoreCase(this.getAudited())) {
            return "未审核";
        } else {
            return "已审核";
        }
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public int getEnterpriseId() {
        return enterpriseId;
    }

    public void setEnterpriseId(int enterpriseId) {
        this.enterpriseId = enterpriseId;
    }

    public String getBillNum() {
        return billNum == null ? "" : billNum.trim();
    }

    public void setBillNum(String billNum) {
        this.billNum = billNum;
    }

    public double getBillSum() {
        return billSum;
    }

    public void setBillSum(double billSum) {
        this.billSum = billSum;
    }

    public Date getOpDate() {
        return opDate;
    }

    public void setOpDate(Date opDate) {
        this.opDate = opDate;
    }

    public String getOperator() {
        return operator == null ? "" : operator.trim();
    }

    public void setOperator(String operator) {
        this.operator = operator;
    }

    public String getBillType() {
        return billType;
    }

    public void setBillType(String billType) {
        this.billType = billType;
    }

    public String getPayTypeNote() {
        return payTypeNote;
    }

    public void setPayTypeNote(String payTypeNote) {
        this.payTypeNote = payTypeNote;
    }

    public Date getCreateTime() {
        return createTime;
    }

    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }

    public Integer getBeProcessed() {
        return beProcessed == null ? 0 : beProcessed;
    }

    public void setBeProcessed(Integer beProcessed) {
        this.beProcessed = beProcessed;
    }

    public void setTickets(List<BillFlightTicket> tickets) {
        this.tickets = tickets;
    }

    public List<BillFlightTicket> getTickets() {
        if (tickets == null) {
          tickets = new ArrayList<>();
        }
        return tickets;
    }

    public Customer getCustomer() {
        return customer;
    }

    public void setCustomer(Customer customer) {
        this.customer = customer;
    }

    public List<BillTrainTicket> getTrainTickets() {
        if (trainTickets == null) {
          trainTickets = new ArrayList<>();
        }

        return trainTickets;
    }

    public void setTrainTickets(List<BillTrainTicket> trainTickets) {
        this.trainTickets = trainTickets;
    }

    public void setHotelBookings(List<BillHotelBooking> hotelBookings) {
        this.hotelBookings = hotelBookings;
    }

    public List<BillHotelBooking> getHotelBookings() {
        if (hotelBookings == null) {
          hotelBookings = new ArrayList<>();
        }
        return hotelBookings;
    }

    public Date getWriteOffDate() {
        return writeOffDate;
    }

    public void setWriteOffDate(Date writeOffDate) {
        this.writeOffDate = writeOffDate;
    }

    public String getBePaid() {
        return bePaid == null ? CUSTOMER_PAYMENT_NOT_RECEIVED : bePaid;
    }

    public void setBePaid(String bePaid) {
        this.bePaid = bePaid;
    }

    public String getReceiptNo() {
        return receiptNo == null ? "" : receiptNo.trim();
    }

    public void setReceiptNo(String receiptNo) {
        this.receiptNo = receiptNo;
    }

    public String getWriteOffMemo() {
        return writeOffMemo;
    }

    public void setWriteOffMemo(String writeOffMemo) {
        this.writeOffMemo = writeOffMemo;
    }

    public String getAudited() {
        return audited == null ? BillInfo.BILL_NOT_AUDITED : audited;
    }

    public void setAudited(String audited) {
        this.audited = audited;
    }

    public String getOp1() {
        return op1;
    }

    public void setOp1(String op1) {
        this.op1 = op1;
    }


    public Date getEtdzDate() {
        return etdzDate;
    }

    public void setEtdzDate(Date etdzDate) {
        this.etdzDate = etdzDate;
    }

    public Integer getCustomerType() {
        return customerType == null ? Customer.ENT_CORPORATION : customerType;
    }

    public void setCustomerType(Integer customerType) {
        this.customerType = customerType;
    }

    public String getOrderNo() {
        return orderNo;
    }

    public void setOrderNo(String orderNo) {
        this.orderNo = orderNo;
    }

    public List<BillFlightRefundTicket> getRefundTickets() {
        if (refundTickets == null) {
            refundTickets = new ArrayList<>();
        }
        return refundTickets;
    }

    public void setRefundTickets(List<BillFlightRefundTicket> refundTickets) {
        this.refundTickets = refundTickets;
    }

    public Date getSettleDate() {
        return settleDate;
    }

    public void setSettleDate(Date settleDate) {
        this.settleDate = settleDate;
    }

    public String getSettlementNo() {
        return settlementNo;
    }

    public void setSettlementNo(String settlementNo) {
        this.settlementNo = settlementNo;
    }

    public String getCostCenter() {
        return costCenter;
    }

    public void setCostCenter(String costCenter) {
        this.costCenter = costCenter;
    }

    public Date getLastUpdate() {
        return lastUpdate;
    }

    public void setLastUpdate(Date lastUpdate) {
        this.lastUpdate = lastUpdate;
    }

    public String getRemark() {
        return remark == null ? "" : remark.trim();
    }

    public void setRemark(String remark) {
        this.remark = remark;
    }

    public List<BillVasOrder> getVasOrders() {
        if (vasOrders == null) {
            vasOrders = new ArrayList<>();
        }
        return vasOrders;
    }

    public void setVasOrders(List<BillVasOrder> vasOrders) {
        this.vasOrders = vasOrders;
    }

    public List<BillChangeOrder> getChangeOrders() {
        if (changeOrders == null) {
            changeOrders = new ArrayList<>();
        }
        return changeOrders;
    }

    public void setChangeOrders(List<BillChangeOrder> changeOrders) {
        this.changeOrders = changeOrders;
    }

    public String getCustomerCode() {
        return customerCode == null ? "" : customerCode.trim();
    }

    public void setCustomerCode(String customerCode) {
        this.customerCode = customerCode;
    }

    public String getProjectName() {
        return projectName == null ? "" : projectName.trim();
    }

    public void setProjectName(String projectName) {
        this.projectName = projectName;
    }

    public String getFlightOrderNo() {
        return flightOrderNo == null ? "" : flightOrderNo.trim();
    }

    public void setFlightOrderNo(String flightOrderNo) {
        this.flightOrderNo = flightOrderNo;
    }

    public String getPayRemark() {
        return payRemark == null ? "" : payRemark.trim();
    }

    public void setPayRemark(String payRemark) {
        this.payRemark = payRemark;
    }

    public Integer getCustomerId() {
        return customerId == null ? 0: customerId;
    }

    public void setCustomerId(Integer customerId) {
        this.customerId = customerId;
    }

    public Integer getIntlTicket() {
        return intlTicket == null ? -1 : intlTicket;
    }

    public void setIntlTicket(Integer intlTicket) {
        this.intlTicket = intlTicket;
    }

    public Integer getTicketCount() {
        return ticketCount;
    }

    public void setTicketCount(Integer ticketCount) {
        this.ticketCount = ticketCount;
    }

    public Date getAuditDate() {
        return auditDate;
    }

    public void setAuditDate(Date auditDate) {
        this.auditDate = auditDate;
    }

    public String getCarrier() {
        return carrier;
    }

    public void setCarrier(String carrier) {
        this.carrier = carrier;
    }

    public int getPaymentStatus() {
        return paymentStatus == null ? 0 : paymentStatus;
    }

    public void setPaymentStatus(Integer paymentStatus) {
        this.paymentStatus = paymentStatus;
    }
}